home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJLSR106.ARJ / MKTEMP.C < prev    next >
C/C++ Source or Header  |  1992-03-02  |  3KB  |  121 lines

  1. /* This is file MKTEMP.C */
  2. /* This file may have been modified by DJ Delorie (Jan 1991).  If so,
  3. ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
  4. ** Rochester NH, 03867-2954, USA.
  5. */
  6.  
  7. /*
  8.  * Copyright (c) 1987 Regents of the University of California.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that: (1) source distributions retain this entire copyright
  13.  * notice and comment, and (2) distributions including binaries display
  14.  * the following acknowledgement:  ``This product includes software
  15.  * developed by the University of California, Berkeley and its contributors''
  16.  * in the documentation or other materials provided with the distribution
  17.  * and in all advertising materials mentioning features or use of this
  18.  * software. Neither the name of the University nor the names of its
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  */
  25.  
  26. #if defined(LIBC_SCCS) && !defined(lint)
  27. static char sccsid[] = "@(#)mktemp.c    5.9 (Berkeley) 6/1/90";
  28. #endif /* LIBC_SCCS and not lint */
  29.  
  30. #include <sys/types.h>
  31. #include <sys/file.h>
  32. #include <sys/stat.h>
  33. #include <errno.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36.  
  37. mkstemp(path)
  38.     char *path;
  39. {
  40.     int fd;
  41.  
  42.     return (_gettemp(path, &fd) ? fd : -1);
  43. }
  44.  
  45. char *
  46. mktemp(path)
  47.     char *path;
  48. {
  49.     return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
  50. }
  51.  
  52. static
  53. _gettemp(path, doopen)
  54.     char *path;
  55.     register int *doopen;
  56. {
  57.     extern int errno;
  58.     register char *start, *trv;
  59.     struct stat sbuf;
  60.     u_int pid;
  61.  
  62.     pid = getpid();
  63.     for (trv = path; *trv; ++trv);        /* extra X's get set to 0's */
  64.     while (*--trv == 'X') {
  65.         *trv = (pid % 10) + '0';
  66.         pid /= 10;
  67.     }
  68.  
  69.     /*
  70.      * check the target directory; if you have six X's and it
  71.      * doesn't exist this runs for a *very* long time.
  72.      */
  73.     for (start = trv + 1;; --trv) {
  74.         if (trv <= path)
  75.             break;
  76.         if (*trv == '/') {
  77.             *trv = '\0';
  78.             if (trv[-1] == ':') {
  79.                 *trv = '/';
  80.                 break;
  81.             }
  82.             if (stat(path, &sbuf))
  83.                 return(0);
  84.             if (!(sbuf.st_mode & S_IFDIR)) {
  85.                 errno = ENOTDIR;
  86.                 return(0);
  87.             }
  88.             *trv = '/';
  89.             break;
  90.         }
  91.     }
  92.  
  93.     for (;;) {
  94.         if (doopen) {
  95.             if ((*doopen =
  96.                 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  97.                 return(1);
  98.             if (errno != EEXIST)
  99.                 return(0);
  100.         }
  101.         else if (stat(path, &sbuf))
  102.             return(errno == ENOENT ? 1 : 0);
  103.  
  104.         /* tricky little algorithm for backward compatibility */
  105.         for (trv = start;;) {
  106.             if (!*trv)
  107.                 return(0);
  108.             if (*trv == 'z')
  109.                 *trv++ = 'a';
  110.             else {
  111.                 if (isdigit(*trv))
  112.                     *trv = 'a';
  113.                 else
  114.                     ++*trv;
  115.                 break;
  116.             }
  117.         }
  118.     }
  119.     /*NOTREACHED*/
  120. }
  121.